package com.qianyu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qianyu.api.ApiCommon;
import com.qianyu.entity.base.BaseIdDto;
import com.qianyu.entity.bean.*;
import com.qianyu.entity.dto.QunDto;
import com.qianyu.entity.vo.QunVo;
import com.qianyu.exception.CustomerException;
import com.qianyu.mapper.QqAccountLogMapper;
import com.qianyu.mapper.QunMapper;
import com.qianyu.service.*;
import com.qianyu.util.CacheKeyUtil;
import com.qianyu.util.RedisUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@RequiredArgsConstructor
public class QunServiceImpl extends ServiceImpl<QunMapper, Qun> implements QunService {

    private final QqAccountService qqAccountService;

    private final QqAccountLogMapper qqAccountLogMapper;

    private final ApiCommon apiCommon;

    private final QunMemberService qunMemberService;

    private final RedisUtil redisUtil;

    private final QhService qhService;

    private final QunYjService qunYjService;

    /**
     * 建群
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveQun(QunDto.QunSaveDto dto) {
        QqAccount account = qqAccountService.getRandomAccount();

        Qun qun = new Qun();
        BeanUtil.copyProperties(dto, qun);
        qun.setQq(account.getQq());

        //调用发包云机
        String machineList = apiCommon.redMachineList(dto.getYjGroup());
        //调用领包云机
        String redMachineList = apiCommon.redMachineList(dto.getCyjGroup());
        JSONObject object = JSONObject.parseObject(machineList);
        JSONObject lbObject = JSONObject.parseObject(redMachineList);
        if (object.getInteger("code") != 0) {
            throw new CustomerException(object.getString("msg"));
        }
        if (lbObject.getInteger("code") != 0) {
            throw new CustomerException(object.getString("msg"));
        }
        JSONArray array = object.getJSONArray("data");
        JSONArray lbArray = lbObject.getJSONArray("data");
        qun.setYjNum(array.size());
        qun.setConfClaimQnum(lbArray.size());
        save(qun);
        List<QunYj> qunYjs = new ArrayList<>();
        for (Object o : array) {
            JSONObject json = (JSONObject) o;
            QunYj yj = new QunYj() {{
                setRole(1);
                setYjNo(json.getString("name"));
                setProvinceCode(json.getString("province_code"));
                setQunId(qun.getId());
            }};
            qunYjs.add(yj);
        }

        for (Object o : lbArray) {
            JSONObject json = (JSONObject) o;
            QunYj yj = new QunYj() {{
                setRole(2);
                setYjNo(json.getString("name"));
                setProvinceCode(json.getString("province_code"));
                setQunId(qun.getId());
            }};
            qunYjs.add(yj);
        }
        qunYjService.saveBatch(qunYjs);
        //设置到建群取号队列
        return redisUtil.lSet(CacheKeyUtil.createQunSet(), qun.getId());
    }

    /**
     * 建群取号
     *
     * @return
     */
    @Override
    public QunVo.QunSimpleVo getAuthQun() {
        return (QunVo.QunSimpleVo) qhService.qh(CacheKeyUtil.createQunSet());
    }

    /**
     * 建群回调
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean qunNotify(QunDto.QunNotifyDto dto) {
        LambdaUpdateWrapper<Qun> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(Qun::getId, dto.getId());
        switch (dto.getStatus()) {
            //账号冻结
            case -1:
                qqAccountService.freezeAccount(dto.getQq(), dto.getRemark());
                break;
            //失败
            case 0:
                wrapper.set(Qun::getStatus, 2);
                break;
            case 1:
                wrapper.set(Qun::getStatus, dto.getStatus())
                        .set(Qun::getScriptNewTime, DateUtil.date())
                        .set(Qun::getLink, dto.getLink())
                        .set(Qun::getRemark, dto.getRemark())
                        .set(Qun::getQunNo, dto.getQunNo());
                QqAccount account = qqAccountService.getOne(Wrappers.<QqAccount>lambdaQuery().eq(QqAccount::getQq, dto.getQq()));
                account.setQunNum(account.getQunNum() + 1);
                account.setLastQunId(dto.getId());
                account.setSeatStatus(1);

                //添加群日志
                QqAccountLog log = new QqAccountLog() {{
                    setQq(dto.getQq());
                    setQunId(dto.getId());
                    setRemark("建群回调");
                    setKey("建群回调");
                }};
                qqAccountLogMapper.insert(log);
                qqAccountService.updateById(account);

                //添加到群成员
                QunMember member = new QunMember() {{
                    setQq(dto.getQq());
                    setRole(account.getRole());
                    setQunId(dto.getId());
                    setJoinTime(new Date());
                    setStatus(1);
                }};
                qunMemberService.save(member);
                break;
        }

        return update(wrapper);
    }

    /**
     * 分页查询群
     *
     * @param dto
     * @return
     */
    @Override
    public Page<Qun> pageList(QunDto.QunPageDto dto) {
        return (Page<Qun>) page(new Page<>(dto.getPageNum(), dto.getPageSize()), Wrappers.<Qun>lambdaQuery()
                .eq(ObjectUtil.isNotNull(dto.getStatus()), Qun::getStatus, dto.getStatus())
                .like(ObjectUtil.isNotEmpty(dto.getName()), Qun::getName, dto.getName()));
    }

    /**
     * 获取群详情
     *
     * @param dto
     */
    @Override
    public Qun getInfo(BaseIdDto dto) {
        return getById(dto.getId());
    }
}
